#import "USMediaPickerManager.h"
#import "USPhotoUploadTool.h"
#import <UniformTypeIdentifiers/UniformTypeIdentifiers.h>
#import <objc/runtime.h>

@interface USMediaPickerManager ()
@property (nonatomic, copy) void (^didFinishPicking)(void);
@property (nonatomic, copy) void (^completion)(NSArray<USMediaResult *> *);
@property (nonatomic, copy) void (^progressHandler)(NSInteger, NSInteger);
@property (nonatomic, strong) NSMutableArray<USMediaResult *> *resultList;
@property (nonatomic, assign) NSInteger totalExpected;
@property (nonatomic, assign) NSInteger finishedCount;
@property (nonatomic, assign) BOOL isSingleAsset;
@end

@implementation USMediaPickerManager

+ (void)presentPickerFrom:(UIViewController *)vc
                     type:(USPickerMediaType)type
                    limit:(NSInteger)limit
         didFinishPicking:(void (^)(void))didFinishPicking
          progressHandler:(void (^)(NSInteger current, NSInteger total))progressHandler
               completion:(void (^)(NSArray<USMediaResult *> *results))completion {
    PHPickerConfiguration *config = [[PHPickerConfiguration alloc] init];
    if (type == USPickerMediaType_Image) {
        config.filter = [PHPickerFilter anyFilterMatchingSubfilters:@[
            PHPickerFilter.imagesFilter
        ]];
    }else if (type == USPickerMediaType_Video) {
        config.filter = [PHPickerFilter anyFilterMatchingSubfilters:@[
            PHPickerFilter.videosFilter
        ]];
    }else if (type == USPickerMediaType_Image_Video) {
        config.filter = [PHPickerFilter anyFilterMatchingSubfilters:@[
            PHPickerFilter.imagesFilter,
            PHPickerFilter.videosFilter
        ]];
    }
     config.selectionLimit = limit;

    PHPickerViewController *picker = [[PHPickerViewController alloc] initWithConfiguration:config];
    USMediaPickerManager *manager = [[USMediaPickerManager alloc] init];
    picker.delegate = manager;
    manager.didFinishPicking = didFinishPicking;
    manager.completion = completion;
    manager.progressHandler = progressHandler;

    objc_setAssociatedObject(picker, @"USMediaPickerManager", manager, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

    [vc presentViewController:picker animated:YES completion:nil];
}

- (void)picker:(PHPickerViewController *)picker didFinishPicking:(NSArray<PHPickerResult *> *)results {
    if (self.didFinishPicking) self.didFinishPicking();
    
    [picker dismissViewControllerAnimated:YES completion:nil];

    if (results.count == 0) {
        if (self.completion) self.completion(@[]);
        return;
    }

    self.resultList = [NSMutableArray arrayWithCapacity:results.count];
    for (NSInteger i = 0; i < results.count; i++) {
        [self.resultList addObject:[USMediaResult new]];
    }

    self.totalExpected = results.count;
    self.finishedCount = 0;
    self.isSingleAsset = (results.count == 1);


    
    [results enumerateObjectsUsingBlock:^(PHPickerResult *result, NSUInteger idx, BOOL *stop) {
    
        NSItemProvider *provider = result.itemProvider;
        NSString *uuid = [[NSUUID UUID] UUIDString];

        if ([provider canLoadObjectOfClass:[PHLivePhoto class]]) {
  
            NSProgress *progress = [provider loadObjectOfClass:[PHLivePhoto class] completionHandler:^(PHLivePhoto *livePhoto, NSError *error) {
                if (livePhoto) {
                    [self saveLivePhotoPreviewImage:livePhoto uuid:uuid completion:^(NSString *photoPath, NSString *videoPath, NSDate *creationDate) {
                    
                        USMediaResult *item = [[USMediaResult alloc] init];
                        item.uuid = uuid;
                        item.livePhoto = livePhoto;
                        item.type = USMediaTypeLivePhoto;
                        item.filePath = photoPath;
                        item.liveMov = videoPath;
                        item.recordDate =  (NSInteger)creationDate.timeIntervalSince1970;
                        item.customDate = (NSInteger)[[NSDate date] timeIntervalSince1970];
                        [self addResult:item atIndex:idx];
                    }];
                } else {
                    [self tryFinishCallbackIfDone];
                }
            }];
            [self observeIfSingleAssetProgress:progress];
            
        } else if ([provider hasItemConformingToTypeIdentifier:UTTypeMovie.identifier]) {
            
        
            
            NSProgress *progress = [provider loadFileRepresentationForTypeIdentifier:UTTypeMovie.identifier completionHandler:^(NSURL *url, NSError *error) {
                if (url) {
                    
                    
//                    因为 url 是 NSItemProvider 提供的临时沙盒路径，生命周期仅在 completionHandler 中有效。一旦跳出，文件就有可能被系统清理。
//
//                    所以你通常需要：
//                        1.    复制一份到自己可控的路径（如 NSTemporaryDirectory()）
//                        2.    然后再用这份新地址做压缩、上传、处理等操作
                    NSString *path = [USPhotoUploadTool videoPathWithUUID:[[NSUUID UUID] UUIDString]];
                    [[NSFileManager defaultManager] copyItemAtURL:url toURL:[NSURL fileURLWithPath:path] error:nil];

                    //压缩之后导出的路径
                    NSURL *outputURL = [NSURL fileURLWithPath:[USPhotoUploadTool videoPathWithUUID:uuid]];

                    AVURLAsset *asset = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:path] options:nil];
                    AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:asset
                                                                                             presetName:AVAssetExportPresetMediumQuality]; // 可选 Low, Medium, Highest

                    exportSession.outputURL = outputURL;
                    exportSession.outputFileType = AVFileTypeMPEG4;
                    exportSession.shouldOptimizeForNetworkUse = YES;

                    [exportSession exportAsynchronouslyWithCompletionHandler:^{
                        if (exportSession.status == AVAssetExportSessionStatusCompleted) {
                            NSLog(@"压缩成功size: %f", outputURL.path.fileSize);
                            
                            NSLog(@"url-Size = %f, path-size = %f",path.fileSize,path.fileSize);

                            NSDate *creationDate = [self getVideoCreationDate:[NSURL fileURLWithPath:path]];

                            USMediaResult *item = [[USMediaResult alloc] init];
                            item.uuid = uuid;
                            item.filePath = outputURL.path;
                            item.type = USMediaTypeVideo;
                            item.recordDate = (NSInteger)creationDate.timeIntervalSince1970;
                            item.customDate = (NSInteger)[[NSDate date] timeIntervalSince1970];

                            [self addResult:item atIndex:idx];

                        } else {
                            NSLog(@"压缩失败: %@", exportSession.error);
                            [self tryFinishCallbackIfDone];

                        }
                    }];
                    
 
                } else {
                    [self tryFinishCallbackIfDone];
                }
            }];
            [self observeIfSingleAssetProgress:progress];

        } else if ([provider canLoadObjectOfClass:[UIImage class]]) {
            NSProgress *progress = [provider loadFileRepresentationForTypeIdentifier:UTTypeImage.identifier completionHandler:^(NSURL *url, NSError *error) {
                if (url) {
                    NSData *data = [NSData dataWithContentsOfURL:url];
                    UIImage *image = [UIImage imageWithData:data];
                    NSString *path = [USPhotoUploadTool imagePathWithUUID:uuid];
                    
                    UIImage *scaledImage = [self scaleImage:image];
                  
                    [UIImageJPEGRepresentation(scaledImage, 0.9) writeToFile:path atomically:YES];
 
                    NSDate *creationDate = [self getImageCreationDate:url];

                    NSLog(@"url-Size = %f, path-size = %f",url.path.fileSize,path.fileSize);
                    USMediaResult *item = [[USMediaResult alloc] init];
                    item.uuid = uuid;
                    item.filePath = path;
                    item.type = USMediaTypeImage;
                    item.recordDate = (NSInteger)creationDate.timeIntervalSince1970;
                    item.customDate = (NSInteger)[[NSDate date] timeIntervalSince1970];

                    [self addResult:item atIndex:idx];
                } else {
                    [self tryFinishCallbackIfDone];
                }
            }];

            [self observeIfSingleAssetProgress:progress];

        } else {
            [self tryFinishCallbackIfDone];
        }
    }];
}
- (UIImage *)scaleImage:(UIImage *)image {
    CGFloat longestSide = MAX(image.size.width, image.size.height);
    
    // 只在超过某个门槛时压缩
    if (longestSide <= 2048) return image;
    
    // 设定压缩后的最长边
    CGFloat targetLongSide = 2048.0;
    CGFloat scale = targetLongSide / longestSide;
    
    CGSize newSize = CGSizeMake(image.size.width * scale, image.size.height * scale);
    UIGraphicsBeginImageContextWithOptions(newSize, NO, image.scale);
    [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
    UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return scaledImage;
}
 
- (void)saveLivePhotoPreviewImage:(PHLivePhoto *)livePhoto
                             uuid:(NSString *)uuid
                       completion:(void (^)(NSString *photoPath, NSString *videoPath, NSDate *creationDate))completion {
    NSArray<PHAssetResource *> *resources = [PHAssetResource assetResourcesForLivePhoto:livePhoto];
    
    
    __block NSString *photoPath = nil;
    __block NSString *videoPath = nil;
    __block NSDate *finalCreationDate = [NSDate date];
    
    dispatch_group_t group = dispatch_group_create();
    
    for (PHAssetResource *resource in resources) {
        if (resource.type == PHAssetResourceTypePhoto) {
            NSString *path = [NSTemporaryDirectory() stringByAppendingPathComponent:
                              [NSString stringWithFormat:@"livephoto_%@.jpg", uuid]];
            NSURL *url = [NSURL fileURLWithPath:path];
       
            dispatch_group_enter(group);
            [[PHAssetResourceManager defaultManager] writeDataForAssetResource:resource
                                                                        toFile:url
                                                                       options:nil
                                                             completionHandler:^(NSError * _Nullable error) {
                if (!error) {
                    photoPath = path;
                    NSDictionary *attrs = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil];
                    if (attrs[NSFileCreationDate]) {
                        finalCreationDate = attrs[NSFileCreationDate];
                    }
                    
                }
                dispatch_group_leave(group);
            }];
        }else if (resource.type == PHAssetResourceTypePairedVideo || resource.type == PHAssetResourceTypeFullSizeVideo) {
            NSString *path = [NSTemporaryDirectory() stringByAppendingPathComponent:
                              [NSString stringWithFormat:@"livephoto_%@.mp4", uuid]];
            NSURL *url = [NSURL fileURLWithPath:path];
            
            dispatch_group_enter(group);

            [[PHAssetResourceManager defaultManager] writeDataForAssetResource:resource
                                                                        toFile:url
                                                                       options:nil
                                                             completionHandler:^(NSError * _Nullable error) {
                if (!error) {
                     videoPath = path;
                }
                dispatch_group_leave(group);
            }];
        }
    }
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        if (completion) {
            completion(photoPath, videoPath, finalCreationDate);
        }
    });
}

//- (NSDate *)getVideoCreationDate:(NSURL *)url {
//    AVAsset *asset = [AVAsset assetWithURL:url];
//    for (NSString *format in [asset availableMetadataFormats]) {
//        for (AVMetadataItem *item in [asset metadataForFormat:format]) {
//            if ([item.commonKey isEqualToString:@"creationDate"] || [item.commonKey isEqualToString:@"com.apple.quicktime.udta"]) {
//                NSString *dateStr = (NSString *)item.value;
//                NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
//                formatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ssZ";
//                NSDate *date = [formatter dateFromString:dateStr];
//                return date ?: [NSDate date]; // fallback 当前时间
//            }
//        }
//    }
//    return [NSDate date];
//}

- (NSDate *)getVideoCreationDate:(NSURL *)url {
    // 1. 尝试从 QuickTime/EXIF 元数据解析
    AVAsset *asset = [AVAsset assetWithURL:url];
    NSArray<AVMetadataItem *> *metadata = [asset metadataForFormat:AVMetadataFormatQuickTimeMetadata];
    for (AVMetadataItem *item in metadata) {
        if ([item.commonKey isEqualToString:AVMetadataCommonKeyCreationDate]) {
            // 解析日期...
        }
    }
    
    // 2. 回退到文件系统时间（关键改进！）
    NSDictionary *fileAttrs = [[NSFileManager defaultManager] attributesOfItemAtPath:url.path error:nil];
    NSDate *fileCreationDate = fileAttrs[NSFileCreationDate];
    if (fileCreationDate){
        
        NSLog(@"fileCreationDate = %@",[fileCreationDate jk_dateWithFormat:@"YYYY/MM/dd"]);
        return fileCreationDate;

    }
    
    // 3. 最终回退到当前时间
    return [NSDate date];
}

- (NSDate *)getImageCreationDate:(NSURL *)url {
    CGImageSourceRef imageSource = CGImageSourceCreateWithURL((__bridge CFURLRef)url, NULL);
    NSDate *date = [NSDate date];
    if (imageSource) {
        CFDictionaryRef properties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, NULL);
        if (properties) {
            NSDictionary *dict = (__bridge NSDictionary *)properties;
            NSDictionary *exif = dict[(NSString *)kCGImagePropertyExifDictionary];
            NSString *dateStr = exif[(NSString *)kCGImagePropertyExifDateTimeOriginal];
            if (dateStr) {
                NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
                formatter.dateFormat = @"yyyy:MM:dd HH:mm:ss";
                date = [formatter dateFromString:dateStr] ?: [NSDate date];
            }
            CFRelease(properties);
        }
        CFRelease(imageSource);
    }
    return date;
}


- (void)observeIfSingleAssetProgress:(NSProgress *)progress {
    if (self.isSingleAsset && self.progressHandler && progress) {
        [progress addObserver:self forKeyPath:@"fractionCompleted" options:NSKeyValueObservingOptionNew context:nil];
    }
}

- (void)addResult:(USMediaResult *)result atIndex:(NSInteger)index {
    @synchronized (self) {
        if (index < self.resultList.count) {
            self.resultList[index] = result;
        }
        [self tryFinishCallbackIfDone];
    }
}


- (void)tryFinishCallbackIfDone {
    @synchronized (self) {
        self.finishedCount++;

        if (!self.isSingleAsset && self.progressHandler) {
            dispatch_async(dispatch_get_main_queue(), ^{
                self.progressHandler(self.finishedCount, self.totalExpected);
            });
        }

        if (self.finishedCount >= self.totalExpected) {
            dispatch_async(dispatch_get_main_queue(), ^{
                if (self.completion) {
                   
                    //剔除掉失败的
                    NSMutableArray *finalList = [NSMutableArray array];
                    for (USMediaResult *media in self.resultList) {
                        if (media.filePath.length > 0) {
                            [finalList addObject:media];
                        }
                    }
                    
                    self.completion([finalList copy]);
                }
            });
        }
    }
}

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary<NSKeyValueChangeKey,id> *)change
                       context:(void *)context {
    if ([keyPath isEqualToString:@"fractionCompleted"] && [object isKindOfClass:[NSProgress class]]) {
        NSProgress *progress = (NSProgress *)object;
        if (self.progressHandler) {
            dispatch_async(dispatch_get_main_queue(), ^{
                self.progressHandler((NSInteger)(progress.fractionCompleted * 100), 100);
            });
        }

        if (progress.fractionCompleted >= 1.0) {
            [progress removeObserver:self forKeyPath:@"fractionCompleted"];
        }
    }
}

@end
